Vue.component('zrow',{
    template:'<div class="row"><slot></slot></div>'
})

Vue.component('zcol',{
    template:'<div :class="mdClass"><slot></slot></div>',
    computed:{
      mdClass:function(){
        return 'col-md-' + this.md ;
      }
    },
    props:{
        md:{
            type: Number,
            default: 12
        }
    }
})

//Vue.component('zinput',{
//    template:'<div class="form-group" :class="{\'has-error\':err}">'+
//    '<label>{{label}}</label>'+
//    '<input type="text" class="form-control" v-model="ctx.form[name]"  :placeholder="label"/>'+
//    '<div v-if="err" class="help-block">{{err}}</div>'+
//    '</div>',
//    props:['label','ctx','name'],
//    data:function(){
//      return {
//          err:''
//      }
//    },
//    mounted:function(){
//        validateWatcher(this)
//    },
//    methods:{
//        va:function(newVal){
//            if(!this.ctx.validate[this.name]){ return }
//            var validates = this.ctx.validate[this.name] ;
//            this.err = validateChecker(validates,newVal)
//        }
//    }
//})


Vue.component('zinput',VueConfigCreator({
    template:'<div class="form-group" :class="{\'has-error\':err}">'+
    '<label>{{label}}</label>'+
    '<input type="text" class="form-control" v-model="ctx.form[name]"  :placeholder="label"/>'+
    '<div v-if="err" class="help-block">{{err}}</div>'+
    '</div>',
    props:['label','ctx','name'],
    data:function(){
      return {
          err:''
      }
    }
}))




Vue.component('ztextarea',{
    template:'<div class="form-group">'+
    '<label>{{label}}</label>'+
    '<textarea :style="{ height:height}" type="text" class="form-control" v-model="ctx.form[name]"  :placeholder="label"/></textarea>'+
    '</div>',
    props:['label','ctx','name','height']
})

Vue.component('zselect',{
    template:'<div class="form-group">'+
    '<label>{{label}}{{chosen}}</label>'+
    '<select ref="select" class="form-control" v-model="ctx.form[name]">'+
    '<option v-for="d in options" :value="d.value" >{{d.label}}</option>'+
    '</select>'+
    '</div>',
    props:['label','ctx','name','data','defaut','chosen'],

    data:function(){
        return {
            opts:[]
        }
    },
    methods:{
        change:function (e) {
            console.log(e)
        }  
    },
    computed:{
        options:function(){

            var _this = this
            if(this.data.then){
                this.data.then(function(d){
                    _this.opts = d
                    if(_this.chosen){
                        _this.$nextTick(function(){
                            $(_this.$refs.select).chosen()
                            $(_this.$refs.select).on('change', function(e){
                                _this.ctx.form[_this.name] = e.target.value ;
                            });
                        })
                    }
                })
            }else{
                this.opts = this.data ;
                if(_this.chosen){
                    if(this.data.length > 0){
                        _this.$nextTick(function(){
                            $(_this.$refs.select).chosen()
                            $(_this.$refs.select).on('change', function(e){
                                _this.ctx.form[_this.name] = e.target.value ;
                            });
                        })
                    }
                }
            }

            if(this.defaut){
                var defaut = this.defaut.split(',')
                return [{"label":defaut[1] , "value":defaut[0]}].concat(this.opts) ;
            }

            return this.opts
        }
    }
})



Vue.component('zcheckbox',{
    template:'<div class="form-group">'+
    '<label>{{label}}</label>'+
    '<div v-if="leveled">'+
    '<label class="checkbox-inline" v-for="d in data"><input type="checkbox"  :value="d.value"  v-model="ctx.form[name]">{{d.label}}</label>'+
    '</div>'+
    '<div v-else>'+
    '<label class="checkbox-inline" v-for="d in data"><input type="checkbox"  :value="d.value"  v-model="ctx.form[name]">{{d.label}}</label>'+
    '</div>'+
    '</div>',
    props:['label','ctx','name','data','leveled']
})

Vue.component('zradio',{
    template:'<div class="form-group">'+
    '<label>{{label}}</label>'+
    '<div>'+
    '<label class="radio-inline" v-for="d in data"><input type="radio"  :value="d.value"  v-model="ctx.form[name]">{{d.label}}</label>'+
    '</div>'+
    '</div>',
    props:['label','ctx','name','data']
})


Vue.component('editor',{
    template:
    '<div class="form-group">'+
        //'<input type="hidden" v-model="ctx.form[name]" ref="hiddenIpt"/>'+
        '<label>{{label}}</label>'+
        '<script :id="id" name="content" type="text/plain"></script>'+
    '</div>',
    data:function(){
        return {
            id: 'ueditorId_' + (Math.random() + '').substr(2)
        }
    },
    props:['label','ctx','name','height'],

    mounted:function(){

        var _this = this ;
        var ueConfig = {} ;
        if(this.height){
            ueConfig.initialFrameHeight = this.height
        }
        this.$nextTick(function(){
            _this.editor = UE.getEditor(this.id,ueConfig);

            setTimeout(function(){
                _this.editor.setContent(_this.ctx.form[_this.name]);
            },1000)


            _this.editor.ready(function() {
                //ue.execCommand('serverparam', '_token', '{{ csrf_token() }}'); // 设置 CSRF token.
                _this.editor.minHeight = 600
                _this.editor.addListener('contentChange',function(){
                    _this.ctx.form[_this.name] = _this.editor.getContent() ;
                })
            });
        })
    }

})

var Va = {
    required:function(v){
        if(v !== ''){
            return undefined ;
        }
        return '必填项'
    },
    maxLength:function(n){
        return function (v){
            if(v.length > n){
                return '最大长度为'+n +'个字符';
            }
            return undefined ;
        }
    }
}




function VueConfigCreator(options){

    if(!options.mounted){
        options.mounted = function(){
            validateWatcher(this)
        }
    }

    var va = function(newVal){
        if(!this.ctx.validate[this.name]){ return }
        var validates = this.ctx.validate[this.name] ;
        this.err = validateChecker(validates,newVal) ;
    }

    if(!options.methods){
        options.methods = {}
    }
    options.methods.va = va

    return options
}

function validateWatcher(vm){

    vm.$watch(function(){
        return vm.ctx.form[this.name] ;
    },function(newVal, oldVal){
        vm.va(newVal)
    })

    vm.$watch(function(){
        console.log('vm.ctx.state',vm.ctx.state.validateSubmiting)
        return vm.ctx.state.validateSubmiting
    },function(newVal, oldVal){
        ///console.log('newVal, oldVal',newVal, oldVal)
        //if(newVal == 'submiting'){
            vm.va(vm.ctx.form[this.name])
        //}
    })
}

function validateChecker(validates,newVal){
    if(isArray(validates)){
        for (var i = 0 ; i < validates.length ; i++){
            var err = validates[i](newVal)
            if(err){
                return err
            }
        }
    }else{
        return validates(newVal)
    }
    return undefined ;
}

function validateAll(vm){
    if(!vm.state.validateSubmiting){
        vm.$set(vm.state,'validateSubmiting',1)
    }else{
        vm.state.validateSubmiting += 1
    }

    for(var filed in vm.validate){
        if(validateChecker(vm.validate[filed],vm.form[filed]) !== undefined){
            return false
        }
    }
    return true
}



function isArray(object){
    return object && typeof object==='object' &&
        Array == object.constructor;
}




